package com.broada.apm.logic.impl;

import java.io.File;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;

import com.broada.apm.ApmServer;
import com.broada.apm.ajax.Result;
import com.broada.apm.base.BaseLogic;
import com.broada.apm.common.util.ZipUtil;
import com.broada.apm.entity.ConfigVariable;
import com.broada.apm.entity.NoticeCommandException;
import com.broada.apm.entity.SSLCertificate;
import com.broada.apm.entity.convert.BeanConvert;
import com.broada.apm.indicator.api.common.ApmDataIndicatorException;
import com.broada.apm.indicator.api.model.Variable;
import com.broada.apm.logic.AnalyzerLogic;
import com.broada.apm.model.Analyzer;
import com.broada.apm.model.ConfigItem;
import com.broada.apm.model.Filter;
import com.broada.apm.model.FilterRule;
import com.broada.apm.model.L7Module;
import com.broada.apm.model.PagingList;
import com.broada.apm.model.RemoteProtocolInfo;
import com.broada.apm.protocol.L7ModuleManager;
import com.broada.apm.protocol.ZeroClient;
import com.broada.apm.util.JsonUtil;
import com.broada.apm.utils.ApmFileUtils;
import com.broada.apm.utils.ExceptionUtils;
import com.broada.apm.utils.IPUtils;
import com.google.common.collect.Lists;
import com.google.common.hash.Hashing;

public class AnalyzerLogicImpl extends BaseLogic implements AnalyzerLogic{
	
	private Logger log = LoggerFactory.getLogger(AnalyzerLogicImpl.class);
	
	@Override
	public Result getAllAnalyzer(int pageIndex, int pageSize){
		Result result = new Result();
		try{
			if(pageSize == 0){ 
				pageSize = 10;
			}
			PagingList<Analyzer> page = analyzerService.getAllAnalyzer(pageIndex, pageSize);
			result.addPagingList(page);
		} catch(Exception e){
			ExceptionUtils.error(log, "查询所有协议分析器信息异常", e);
			result.setFailMessage("查询所有协议分析器信息异常");
		}
		return result;
	}
	
	@Override
	public Result addAnalyzer(Analyzer analyzer){ 
		Result result = new Result();
		if(StringUtils.isBlank(analyzer.getIp()) || StringUtils.isBlank(analyzer.getPort())){
			result.setFailMessage("ip和port字段不能为空");
			return result;
		}
		if(StringUtils.isBlank(analyzer.getName())){
			analyzer.setName(analyzer.getIp()+":"+analyzer.getPort());
		}
		try {
			ZeroClient client = new ZeroClient();
			client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
			String analyzer_version = client.print_version();
			client.close();
			if(StringUtils.isBlank(analyzer_version)){
				result.setFailMessage("请提供正确的ip和端口信息");
				return result;
			}
			ConfigItem config = configItemService.getConfigItem("analyzer_version");
			if(!config.getValue().equals(analyzer_version.substring(0, 3))){
				result.setFailMessage("要添加的协议分析器版本与主版本不一致");
				return result;
			}
			Analyzer exist = analyzerService.queryAnalyzerByIpAndPort(analyzer);
			if(exist == null){
				String id = Hashing.murmur3_32()
		                .hashString(new StringBuffer().append(analyzer.getIp()).append(":").append(analyzer.getPort()).toString(), Charset.defaultCharset())
		                .toString();    // id由ip和port唯一确定
				analyzer.setId(id);
				List<FilterRule> rules = configItemService.getAllFiltersJson(id);   // 协议分析器升级遗留的数据包过滤规则
				String server_add = "tcp://" + analyzer.getIp() + ":" + analyzer.getPort();
				// 清空已经配置过的协议分析器各种规则
				client = new ZeroClient();
				client.connect(server_add);
				client.init();
				client.commit();
				// 添加协议分析器时，默认全部接受
//				client.filter_setdefault(true);
//				client.commit();
				client.close();
				try{
					// 插入一条全局规则并下发遗留的数据包过滤规则
					filterAdd(id, server_add, rules);
				}catch(Exception e) {
					ExceptionUtils.error(log, "下发数据包过滤规则异常", e);
					result.setFailMessage("数据包过滤规则下发" + analyzer.getName() + "协议分析器端异常");
					return result;
				}
				try{
					// 下发lua
					luaSetup(server_add, analyzer.getName());
				}catch(Exception e) {
					ExceptionUtils.error(log, "下发lua脚本异常", e);
					result.setFailMessage("lua下发" + analyzer.getName() + "协议分析器端异常");
					return result;
				}
				try{
					// 下发ssl
					sslSetup(server_add, analyzer.getName());
				}catch(Exception e) {
					ExceptionUtils.error(log, "下发ssl证书异常", e);
					result.setFailMessage("ssl证书下发" + analyzer.getName() + "协议分析器端异常");
					return result;
				}
				analyzerService.addAnalyzer(analyzer);   // 不存在则增加
				new Thread(new Runnable() {     // 另起线程
					@Override
					public void run() {
						initAnalyzerStatus(analyzer);
					}
				}).start();
				
			}else{
				result.setFailMessage("已配置过该协议分析器");
			}
		} catch (Exception e) {
			ExceptionUtils.error(log, "配置协议分析器数据包过滤信息异常", e);
			result.setFailMessage("配置协议分析器数据包过滤信息异常" + e.getMessage());
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Result deleteAnalyzer(String id) throws ApmDataIndicatorException{
		Result result = new Result();
		if(StringUtils.isBlank(id)){ 
			result.setFailMessage("id字段不能为空");
			return result;
		}
		try {  
			// 清空远程协议分析器数据包过滤规则
			Analyzer analyzer = analyzerService.getAnalyzerById(id);
			ZeroClient client = new ZeroClient();
			client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
			Result filter = this.getFilters(id);
			List<FilterRule> filterList = (List<FilterRule>) filter.get("result");
			if(filterList == null || filterList.size() < 1){
				// 什么也不做 
			}else{
				client.filter_clear();   //删除
				client.commit();
			}
			client.filter_setdefault(false);   // 默认drop
			client.commit();
			try{
				client.lua_clear();  // 清空lua
				client.commit();
				client.close();
			}catch(Exception e){
				ExceptionUtils.error(log, "删除协议分析器lua异常", e);   //发生异常记录日志
//				throw new ApmDataIndicatorException("删除协议分析器lua异常", e);
			}
			try{
				sslDelete("tcp://" + analyzer.getIp() + ":" + analyzer.getPort(), analyzer.getName());                     // 遍历循环删除ssl
			}catch(Exception e){
				ExceptionUtils.error(log, "删除协议分析器ssl证书异常", e);   //发生异常记录日志
//				throw new ApmDataIndicatorException("删除协议分析器ssl证书异常", e);
			}
		} catch (Exception e) {
			ExceptionUtils.error(log, "删除协议分析器数据包过滤信息异常", e);   //发生异常记录日志
//			throw new ApmDataIndicatorException("删除协议分析器数据包过滤信息异常", e);
		}
		configItemService.deleteFilter(id);    // 删除本地数据包过滤信息
		if(!deleteAnalyzerStatus(id)){  //   禁用/删除远程协议分析器信息
			result.setFailMessage("删除协议分析器错误");
			return result;
		}
		try{
			analyzerService.deleteAnalyzer(id);    // 删除协议分析器信息
//			RemoteProtocolInfo exist = new RemoteProtocolInfo();
//			exist.setAnalyzerId(id);
//			if(l7ModuleService.getRemoteProtocolInfoByAnalyzerId(exist) != null && l7ModuleService.getRemoteProtocolInfoByAnalyzerId(exist).size() > 0){
//				result.setFailMessage("删除协议分析器错误");
//				return result;
//			}else{
//			}
		} catch(Exception e){
			ExceptionUtils.error(log, "删除协议分析器异常", e);
			result.setFailMessage("删除协议分析器异常");
		}
		return result;
	}

	@Override
	public Result getFilters(String analyzerId) {
		Result result = new Result();
		if(StringUtils.isBlank(analyzerId)){
			result.setFailMessage("协议分析标识和查询类型不能为空");
			return result;
		}
		try{
			// 查询数据包过滤规则
			List<FilterRule> filterList = configItemService.getAllFiltersJson(analyzerId);
			result.put("result", filterList);
		} catch(Exception e){
			result.setFailMessage("根据协议分析标识查询信息异常");
			return result;
		}
		return result;
	}

	@Override
	public List<Filter> addConfigData(ConfigVariable variable, String analyzerId)
			throws ApmDataIndicatorException, NoticeCommandException {
		if (variable != null) {
			int confType = variable.getConfType();
			Variable[] varConf = variable.getConfData();
			List<Filter> filterList = Lists.newArrayList();
			for(Variable var : varConf) {
				String key = variable.getSettingKey(var.getId());
				String value = (String) var.getItem().get("value");
//				ConfigItem configItem = new ConfigItem(key, value);
				if(key != null) {
					if (4 == confType && key.equals("filter.rules")){
						if (value != null) {
							filterList.addAll(setFilter(value, analyzerId));
						}
					}else {
						// 更新默认规则
//						configItemService.updateConfigItem(configItem);
					}
				}
			}
			if (4 == confType && StringUtils.isNotBlank(analyzerId)) {
				configItemService.saveFilter(filterList);   // 保存到filter表中记录前端设置的过滤信息
				List<Filter> filters = configItemService.getAllFilters(analyzerId);
			    L7ModuleManager.filterPackage(analyzerId);  // 设置后即生效!
			    return filters;
			}
		}
		return null;
	}
	
	private List<Filter> setFilter(String value, String analyzerId) {

		List<Filter> filterList = Lists.newArrayList();
		
		List<FilterRule> rules = JsonUtil.getInstance().json2List(value, FilterRule.class);
		if (rules != null && rules.size() > 0) {
			for (FilterRule rule : rules) {
				Filter filter = new Filter();
				filter.setSrcFromIp("");
				filter.setSrcToIp("");
				filter.setSrcFromPort("");
				filter.setSrcToPort("");
				
				filter.setDstFromIp("");
				filter.setDstToIp("");
				filter.setDstFromPort("");
				filter.setDstToPort("");
				filter.setPolicys("");
				filter.setAnalyzerId("");
				if (rule.getdIp() != null && rule.getdIp().length() > 0) {  // 目的
					String[] ip = rule.getdIp().split("-");
					filter.setDstFromIp(ip[0]);
					if (ip.length > 1) {
						filter.setDstToIp(ip[1]);
					}
				}
				if (rule.getsIp() != null && rule.getsIp().length() > 0) {
					String[] ip = rule.getsIp().split("-");
					filter.setSrcFromIp(ip[0]);
					if (ip.length > 1) {
						filter.setSrcToIp(ip[1]);
					}
				}
				if (rule.getdPort() != null && rule.getdPort().length() > 0) {
					String[] port = rule.getdPort().split("-");
					filter.setDstFromPort(port[0]);
					if (port.length > 1) {
						filter.setDstToPort(port[1]);
					}
				}
				if (rule.getsPort() != null && rule.getsPort().length() > 0) {
					String[] port = rule.getsPort().split("-");
					filter.setSrcFromPort(port[0]);
					if (port.length > 1) {
						filter.setSrcToPort(port[1]);
					}
				}

				filter.setPolicys(rule.getPolicys());
				filter.setAnalyzerId(analyzerId);
				filterList.add(filter);
			}
		}else{
			Filter filter = new Filter();
			filter.setAnalyzerId(analyzerId);
			filterList.add(filter);
		}
		return filterList;
	}
	
	public static File getZip(L7Module module, String tempPath) throws Exception{
		String fileName = module.getName() + ".mod";
		String destPath = tempPath + "/" + fileName;
		String zipPath = ApmServer.L7_MODULE_DIR + module.getL7_proto() + "/" + module.getVersion();
		File dirs = new File(ApmServer.L7_MODULE_DIR + module.getL7_proto());
		List<File> files = Arrays.asList(dirs.listFiles());
		Collections.sort(files, new Comparator<File>() {
			@Override
			public int compare(File o1, File o2) {
				Long f1 = Long.valueOf(o1.lastModified());
				Long f2 = Long.valueOf(o2.lastModified());
				return f2.compareTo(f1) ;
			}
		});
		zipPath = ApmServer.L7_MODULE_DIR + module.getL7_proto() + "/" + files.get(0).getName();
//		for (File childFile : dirs.listFiles()) {
//			String filename = childFile.getName();
//			long temp = 0l;
//			if (filename.trim().length() > module.getVersion().trim().length()) {
//				filename = filename.substring(module.getVersion().length(), filename.length());
//				temp = Long.valueOf(filename) > temp ? Long.valueOf(filename) : temp;
//				zipPath = ApmServer.L7_MODULE_DIR + module.getL7_proto() + "/" + childFile.getName();
//			}
//		}
		ZipUtil.zip(zipPath, destPath, null);
		return ApmFileUtils.getAbsoluteFile(destPath);
	}
	
	/**
	 * 添加协议分析器时自动安装已有的协议
	 * @param analyzer
	 */
	//  新增协议分析器时，默认安装并启用已有的协议分析
	@SuppressWarnings("unused")
	private void initAnalyzerStatus(Analyzer analyzer){
		String tempPath = FileUtils.getTempDirectory().getAbsolutePath();
		List<L7Module> modules = l7ModuleService.getAllL7Modules();
		if(modules != null && modules.size() > 0){   //未添加协议
			// 安装
			for(L7Module module : modules){
				RemoteProtocolInfo info = new RemoteProtocolInfo();
				info.setAnalyzerId(analyzer.getId());
				info.setL7_proto(module.getL7_proto());
				info.setVersion(module.getVersion());
				info.setProto_name(module.getCname());
				info.setCallTime(Calendar.getInstance().getTime());
				RemoteProtocolInfo rpi = l7ModuleService.queryRemoteProtocolInfo(info);
				try{
					File file = getZip(module, tempPath);    //安装使用文件
					ZeroClient client = new ZeroClient();
					client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
					if(client.module_uploadremote(module.getL7_proto(), file.getAbsolutePath())){  //远程安装命令
						client.commit();
						client.close();
						info.setErrorMessage("安装协议成功");
						info.setStatus(RemoteProtocolInfo.INSTALL_SUCCESS);
					}
				} catch(Exception e){
					info.setErrorMessage("安装协议失败" + e.getMessage());
					info.setStatus(RemoteProtocolInfo.INSTALL_ERROR);
				}
				if(rpi != null){
					l7ModuleService.updateRemoteProtocolInfo(info);
				}else{
					info.setId(UUID.randomUUID().toString());
					l7ModuleService.addRemoteProtocolInfo(info);
				}
			}
			// 启用
			for(L7Module module : modules){
				if(module.getStatus() == 0){
					RemoteProtocolInfo info = new RemoteProtocolInfo();
					info.setAnalyzerId(analyzer.getId());
					info.setL7_proto(module.getL7_proto());
					info.setVersion(module.getVersion());
					info.setProto_name(module.getCname());
					info.setCallTime(Calendar.getInstance().getTime());
					RemoteProtocolInfo rpi = l7ModuleService.queryRemoteProtocolInfo(info);
					try {
						if(rpi != null && rpi.getStatus() != RemoteProtocolInfo.INSTALL_ERROR && rpi.getStatus() != RemoteProtocolInfo.ENABLE_SUCCESS){
							ZeroClient client = new ZeroClient();
							client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
							if(client.module_enableremote(module.getL7_proto())){
								info.setErrorMessage("启用协议成功");
								info.setStatus(RemoteProtocolInfo.ENABLE_SUCCESS);
							}
							client.commit();
							client.close();
							if(rpi != null){
								l7ModuleService.updateRemoteProtocolInfo(info);
							} else{
								info.setId(UUID.randomUUID().toString());
								l7ModuleService.addRemoteProtocolInfo(info);
							}
						}
					} catch (Exception e) {
						info.setStatus(RemoteProtocolInfo.ENABLE_ERROR);
						info.setErrorMessage("启用协议失败" + e.getMessage());
						l7ModuleService.updateRemoteProtocolInfo(info);
					}
				}
			}
		}
	}
	
	/**
	 * 删除协议分析器
	 * @param id
	 * @return
	 */
	private boolean deleteAnalyzerStatus(String id){
		boolean flag = true;   //是否正常禁用删除
		RemoteProtocolInfo info = new RemoteProtocolInfo();
		info.setAnalyzerId(id);
		List<RemoteProtocolInfo> infos = l7ModuleService.getRemoteProtocolInfoByAnalyzerId(info);
		if(infos != null && infos.size() > 0){
			for(RemoteProtocolInfo rpi: infos){
				Analyzer analyzer = analyzerService.getAnalyzerById(id);
				try {    //禁用
					ZeroClient client = new ZeroClient();
					client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
					if(rpi != null && (rpi.getStatus() != RemoteProtocolInfo.DISABLE_SUCCESS && rpi.getStatus() != RemoteProtocolInfo.INSTALL_ERROR)){
						if(client.module_disenableremote(rpi.getL7_proto())){
							rpi.setErrorMessage("禁用协议成功");
							rpi.setStatus(RemoteProtocolInfo.DISABLE_SUCCESS);
						}
						client.commit();
						client.close();
						l7ModuleService.updateRemoteProtocolInfo(rpi);
					}
				} catch (Exception e) {
					rpi.setErrorMessage("禁用协议失败" + e.getMessage());
					rpi.setStatus(RemoteProtocolInfo.DISABLE_ERROR);
					l7ModuleService.updateRemoteProtocolInfo(rpi);
					flag = false;
					break;
				}
				try {    //删除
					if(rpi.getStatus() == RemoteProtocolInfo.DISABLE_SUCCESS){   //禁用成功的进行删除
						ZeroClient client = new ZeroClient();
						client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
						if(client.module_delremote(rpi.getL7_proto())){   //删除成功
							client.commit();
							client.close();
							l7ModuleService.deleteRemoteProtocolInfo(rpi);
						}
					}
					if(rpi.getStatus() == RemoteProtocolInfo.INSTALL_ERROR){   //安装不成功的进行删除
						l7ModuleService.deleteRemoteProtocolInfo(rpi);
					}
				} catch (Exception e) {
					// 成功禁用，但未能删除的不做任何操作
					flag = false;
					break;
				}
			}
		}
		return flag;
	}

	@Override
	public Result getAnalyzerLog(String analyzerId) {
		Result result = new Result();
		try {
			List<RemoteProtocolInfo> rpis = analyzerService.getAnalyzerLog(analyzerId);
//			if(rpis != null && rpis.size() > 0){   //将协议名称写入实体
//				for(RemoteProtocolInfo rpi : rpis){
//					rpi.setProto_name(l7ModuleService.getL7ModuleById(String.valueOf(rpi.getL7_proto()))==null? "": l7ModuleService.getL7ModuleById(String.valueOf(rpi.getL7_proto())).getCname());
//				}
//			}
			result.put("logs", rpis);
		} catch (Exception e) {
			ExceptionUtils.error(log, "查询协议分析器异常", e);
			result.setFailMessage("查询协议分析器异常");
		}
		return result;
	}

	@Override
	public Result reloadProtocol(String analyzerId) {
		RemoteProtocolInfo info = new RemoteProtocolInfo();
		info.setAnalyzerId(analyzerId);
		List<RemoteProtocolInfo> infos = l7ModuleService.getRemoteProtocolInfoByAnalyzerId(info);
		if(infos != null && infos.size() > 0){
			for(RemoteProtocolInfo rpi : infos){
				L7Module module = l7ModuleService.getL7ModuleById(rpi.getL7_proto()+"");
				Analyzer analyzer = analyzerService.getAnalyzerById(analyzerId);
				if(rpi.getStatus() == RemoteProtocolInfo.INSTALL_SUCCESS
						|| rpi.getStatus() == RemoteProtocolInfo.ENABLE_SUCCESS
						|| rpi.getStatus() == RemoteProtocolInfo.DISABLE_SUCCESS){
					continue;
				}
				if(module != null){
					if(rpi.getStatus() == RemoteProtocolInfo.INSTALL_ERROR){ //安装不成功进行安装
						installProtocol(module, analyzer, rpi);
						RemoteProtocolInfo exist = l7ModuleService.queryRemoteProtocolInfo(rpi);
						if(exist.getStatus() == RemoteProtocolInfo.INSTALL_ERROR){//安装成功才能继续
							continue;
						}
						// 协议是启用状态
						if(module.getStatus() == 0){
							enableProtocol(module, analyzer, rpi);
						}else if(module.getStatus() == 1){ //协议是禁用状态
							disableProtocol(module, analyzer, rpi);
						}
					}
					if(rpi.getStatus() == RemoteProtocolInfo.ENABLE_ERROR){ //启用不成功的
						if(module.getStatus() == 0){
							enableProtocol(module, analyzer, rpi);
						}else if(module.getStatus() == 1){
							disableProtocol(module, analyzer, rpi);
						}
					}
					if(rpi.getStatus() == RemoteProtocolInfo.DISABLE_ERROR){ //禁用不成功的
						if(module.getStatus() == 0){
							enableProtocol(module, analyzer, rpi);
						}else if(module.getStatus() == 1){
							disableProtocol(module, analyzer, rpi);
						}
					}
				}else{
					if(rpi.getStatus() == RemoteProtocolInfo.DISABLE_ERROR){   // 协议已删除，但存在个别的分析器由于禁用失败而未被删除
						module = new L7Module();
						module.setL7_proto(rpi.getL7_proto());
						disableProtocol(module, analyzer, rpi);
						RemoteProtocolInfo exist = l7ModuleService.queryRemoteProtocolInfo(rpi);
						if(exist.getStatus() == RemoteProtocolInfo.DISABLE_SUCCESS){  //禁用成功了即可删除该记录
							l7ModuleService.deleteRemoteProtocolInfo(exist);
						}
					}else{
						continue;
					}
				}
				
			}
		}
		return new Result();
	}
	
	/**
	 * 安装协议
	 * @param module
	 * @param analyzer
	 * @param rpi
	 */
	private void installProtocol(L7Module module, Analyzer analyzer, RemoteProtocolInfo rpi){
		try {
			String tempPath = FileUtils.getTempDirectory().getAbsolutePath();
			File file = getZip(module, tempPath);
			ZeroClient client = new ZeroClient();
			client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
			if(client.module_uploadremote(module.getL7_proto(), file.getAbsolutePath())){
				client.commit();
				rpi.setStatus(RemoteProtocolInfo.INSTALL_SUCCESS);
				rpi.setErrorMessage("安装协议成功");
				l7ModuleService.updateRemoteProtocolInfo(rpi);
				client.close();
			}
		} catch (Exception e) {
			rpi.setStatus(RemoteProtocolInfo.INSTALL_ERROR);
			rpi.setErrorMessage("安装协议失败" + e.getMessage());
			l7ModuleService.updateRemoteProtocolInfo(rpi);
		}
	}
	
	/**
	 * 启用协议
	 * @param module
	 * @param analyzer
	 * @param rpi
	 */
	private void enableProtocol(L7Module module, Analyzer analyzer, RemoteProtocolInfo rpi){
		try{
			ZeroClient client = new ZeroClient();
			client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
			if(client.module_enableremote(module.getL7_proto())){
				client.commit();
				rpi.setStatus(3);
				rpi.setErrorMessage("启用协议成功");
				l7ModuleService.updateRemoteProtocolInfo(rpi);
				client.close();
			}
		}catch(Exception e){
			rpi.setStatus(4);
			rpi.setErrorMessage("启用协议失败" + e.getMessage());
			l7ModuleService.updateRemoteProtocolInfo(rpi);
		}
	}
	
	/**
	 * 禁用协议
	 * @param module
	 * @param analyzer
	 * @param rpi
	 */
	private void disableProtocol(L7Module module, Analyzer analyzer, RemoteProtocolInfo rpi){
		try{
			ZeroClient client = new ZeroClient();
			client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
			if(client.module_disenableremote(module.getL7_proto())){
				client.commit();
				rpi.setStatus(5);
				rpi.setErrorMessage("禁用协议成功");
				l7ModuleService.updateRemoteProtocolInfo(rpi);
				client.close();
			}
		}catch(Exception e){
			rpi.setStatus(6);
			rpi.setErrorMessage("禁用协议失败" + e.getMessage());
			l7ModuleService.updateRemoteProtocolInfo(rpi);
		}
	}

	@Override
	public Analyzer getAnalyzerById(String analyzerId) {
		Analyzer analyzer = analyzerService.getAnalyzerById(analyzerId);
		return analyzer;
	}

	@Override
	public Result deleteFilters(String analyzerId) {
		Result result = new Result();
		try{
			Analyzer analyzer = analyzerService.getAnalyzerById(analyzerId);
			if(analyzer != null){
				ZeroClient client = new ZeroClient();
				client.connect("tcp://" + analyzer.getIp() + ":" + analyzer.getPort());
				client.filter_clear();   //删除
				client.commit();
				client.filter_setdefault(false);   // 默认drop
				client.commit();
				client.close();
			}else{
				result.setFailMessage("查询协议分析器失败");
			}
			configItemService.deleteFilter(analyzerId);
		}catch(Exception e){
			result.setFailMessage("删除协议分析器过滤包信息失败");
		}
		return result;
	}
	
	/**
	 * 下发lua
	 * @param addr
	 * @param lua
	 */
	private void luaSetup(String addr, String name) throws Exception{
		List<com.broada.apm.model.Service> services = serviceService.getAllDisService();
		try{
			if(services != null && services.size() > 0){
				String lua = "";
				for(com.broada.apm.model.Service service:services){
					lua = service.getLua();
					if(StringUtils.isNotBlank(lua)){
						ZeroClient client = new ZeroClient();
						client.connect(addr);
						client.lua_setup(IPUtils.toLittleEndianInteger(service.getIp()), service.getPort(), lua);
						client.commit();
						client.close();
					}
				}
			}
		}catch(Exception e){
			ExceptionUtils.error(log, "lua下发" + name + "协议分析器端异常", e);
			throw new Exception("lua下发" + name + "协议分析器端异常", e);
		}
	}
	
	/**
	 * 下发ssl
	 * @param addr
	 * @param ssl
	 */
	private void sslSetup(String addr, String name) throws Exception{
		List<com.broada.apm.model.Service> services = serviceService.getAllDisService();
		try{
			if(services != null && services.size() > 0){
				for(com.broada.apm.model.Service service:services){
					SSLCertificate vo_sslCertificate = new SSLCertificate();
					com.broada.apm.model.SSLCertificate ssls = serviceService.getSSLBySericeId(service.getId());
					if (ssls == null) {
						continue;
					}
					// data对象转front对象
					BeanConvert.copyBean(vo_sslCertificate, ssls);
					File out = new File(FileUtils.getTempDirectory().getAbsolutePath(), "out");
					FileCopyUtils.copy((byte[]) vo_sslCertificate.getPrivateKey(), out);
					ZeroClient client = new ZeroClient();
					client.connect(addr);
					client.ssl_setup(IPUtils.toLittleEndianInteger(service.getIp()), service.getPort(), out.getAbsolutePath(), vo_sslCertificate.getSslPwd());
					client.commit();
					client.close();
				}
			}
		}catch(Exception e){
			ExceptionUtils.error(log, "ssl证书下发" + name + "协议分析器端异常", e);
			throw new Exception("ssl证书下发" + name + "协议分析器端异常", e);
		}
	}
	
	/**
	 * 删除ssl证书
	 * @param addr
	 * @param name
	 * @throws Exception
	 */
	private void sslDelete(String addr, String name) throws Exception{
		List<com.broada.apm.model.Service> services = serviceService.getAllDisService();
		try{
			if(services != null && services.size() > 0){
				for(com.broada.apm.model.Service service:services){
					SSLCertificate vo_sslCertificate = new SSLCertificate();
					com.broada.apm.model.SSLCertificate ssls = serviceService.getSSLBySericeId(service.getId());
					if (ssls == null) {
						continue;
					}
					ZeroClient client = new ZeroClient();
					client.connect(addr);
					client.ssl_setup(IPUtils.toLittleEndianInteger(service.getIp()), service.getPort(), null, vo_sslCertificate.getSslPwd());
					client.commit();
					client.close();
				}
			}
		}catch(Exception e){
			ExceptionUtils.error(log, name + "协议分析器端删除ssl证书异常", e);
			throw e;
		}
	}

	@Override
	public Result addFilter(Filter filter) throws ApmDataIndicatorException{
		Result result = new Result();
		try (ZeroClient client = new ZeroClient()){
			Analyzer analyzer = analyzerService.getAnalyzerById(filter.getAnalyzerId());
			String server_add = "tcp://" + analyzer.getIp() + ":" + analyzer.getPort();
			client.connect(server_add);
			client.filter_add(0, conjoinNull(filter.getSrcFromIp(), filter.getSrcToIp()), conjoinNull(filter.getSrcFromPort(), filter.getSrcToPort()), 
					conjoinNull(filter.getDstFromIp(), filter.getDstToIp()), conjoinNull(filter.getDstFromPort(), filter.getDstToPort()) , "ACCEPT".equals(filter.getPolicys()));
			client.commit();
			client.close();
		} catch (Exception e) {
			ExceptionUtils.error(log, "设置协议分析器数据包规则失败", e);
			throw new ApmDataIndicatorException("设置协议分析器数据包规则失败", e);
		}
		configItemService.saveFilter(filter);
		return result;
	}

	@Override
	public Result deleteFilterById(String analyzerId, String id) throws ApmDataIndicatorException{
		Result result = new Result();
		try (ZeroClient client = new ZeroClient()){
			Analyzer analyzer = analyzerService.getAnalyzerById(analyzerId);
			String server_add = "tcp://" + analyzer.getIp() + ":" + analyzer.getPort();
			client.connect(server_add);
			List<FilterRule> filterList = configItemService.getAllFiltersJson(analyzerId);
			if(filterList != null && filterList.size() > 0){
				client.filter_clear();
				client.commit();
				for(FilterRule rule:filterList){
					if(!rule.getId().equals(id)){
						client.filter_add(0, rule.getsIp(), rule.getsPort(), rule.getdIp(), rule.getdPort(), "ACCEPT".equals(rule.getPolicys()));
						client.commit();
					}
				}
			}
			client.close();
		} catch (Exception e) {
			ExceptionUtils.error(log, "设置协议分析器数据包规则失败", e);
			throw new ApmDataIndicatorException("设置协议分析器数据包规则失败", e);
		}
		configItemService.deleteFilterById(id);
		return result;
	}
	
	/**
	 * 转换空值成json
	 * @return
	 */
	private String conjoinNull(String src1, String src2){
		if(StringUtils.isBlank(src1) && StringUtils.isBlank(src2)){
			return null;
		}else if(StringUtils.isBlank(src1)){
			return src2;
		}else if(StringUtils.isBlank(src2)){
			return src1;
		}else{
			return src1 + "-" + src2;
		}
	}
	
	/**
	 * 下发遗留的数据包过滤规则
	 * @param addr
	 * @param list
	 * @throws Exception 
	 */
	private void filterAdd(String analyzerId, String addr, List<FilterRule> rules) throws Exception{
		ZeroClient client = new ZeroClient();
		if(rules != null && rules.size() > 0){
			client.connect(addr);
			for(FilterRule rule:rules){
				client.filter_add(0, rule.getsIp(), rule.getsPort(), rule.getdIp(), rule.getdPort(), "ACCEPT".equals(rule.getPolicys()));
			}
			ConfigItem item = configItemService.getConfigItem("filter.default_policy");
			if(item != null && "DROP".equals(item.getValue())){
				client.filter_setdefault(false);
				// 向数据库中插入一条数据
				Filter filter = new Filter();
				filter.setAnalyzerId(analyzerId);
				filter.setDstFromIp("0.0.0.0");
				filter.setDstToIp("0.0.0.0");
				filter.setDstFromPort("0");
				filter.setDstToPort("0");
				filter.setSrcFromIp("");
				filter.setSrcToIp("");
				filter.setSrcFromPort("");
				filter.setSrcToPort("");
				filter.setPolicys("DROP");
				configItemService.saveFilter(filter);
			}
			client.commit();
			client.close();
		}
	}
}
